﻿import flash.display.BitmapData;
import mx.transitions.*;
import mx.transitions.easing.*;
import flash.filters.ColorMatrixFilter;
class ru.vega_int.firsoff.ImageViewer 
{
	/**
	*@author Firsoff Maxim, icq:235859730, e-mail:firsoff_maxim@mail.ru
	*@description Управляет загрузкой изображений в контейнер
 	*/
	
	//// PROPERTIES
	//	private
	private var target:MovieClip;		// клип-носитель
	private var container:MovieClip;	// клип-контейнер для изображения
	private var	image:MovieClip;		// клип-носитель для изображения
	private var	imageEffect:MovieClip;	// клип-носитель для изображения с эффектом
	private var mask:MovieClip;			// клип-маска
	private var border:MovieClip;		// клип-рамка
	private var url:String;				// ссылка для фотки
	private var btmImage:BitmapData;	// битмап дата для фотки
	private var width:Number;			// ширина для фотки
	private var height:Number;			// высота для фотки
	private var align:String;			// выравнивание
	private var borderEnable:Boolean;	// нужна ли рамка
	private var borderStyle:Object;		// стиль рамки
	private var sharpBMP:Boolean;		// нужно ли сглаживание?
	private var fadeEnable:Boolean;		// нужно ли плавное появление
	private var noneResize:Boolean;		// нужен ли ресайз под контейнер
	private var useBitmap:Boolean;		// нужен ли ресайз под контейнер
	private var loader:MovieClipLoader;	// загрузчик
	private var fadeInManager:TransitionManager;	// менеджер появления
	private var loadingCollector:Object;	// сборщик инфы по загрузке
	
	
	private var effectType:String;		// тип эффекта
	/*const*/
	private static var BORDER_THICKNESS:Number;	// толщина обводки
	private static var BORDER_ALPHA:Number;		// прозрачность обводки
	private static var BORDER_COLOR:Number;		// цвет обводки
	
	private static var IMAGE_DEPTH:Number;		// слой для мувика с изображением
	private static var BORDER_DEPTH:Number;		// слой для мувика-обводки
	private static var MASK_DEPTH:Number;		// слой для мувика-маски
	private static var EFFECT_DEPTH:Number;		// слой для эффекта
	private static var FADE_IN_TIME:Number;		// время фэйда
	private static var DEFAULT_BORDER_STYLE:Object;	// стиль для обводки по умолчанию
	// 	public
	var onProgress:Function;					// функция обработчик вызывается при получении порции данных
	var onLoad:Function;						// при загрузке и инициализации
	var onError:Function;						// при ошибке
	
	
	//конструктор ImageViewer
	/**
	*@ param target - клип приемник
	*@ param url - ссылка
	*@ param width - ширина фотки
	*@ param height - высота фотки
	*@ param align - выравнивание 
	*@ param borderEnable - нужна ли рамка
	*@ param fadeEnable - всплытие из альфы
	*@ param borderStyle - стиль для обводки {thickness, color, alpha, indent}
	*@ param sharpBMP - флаг сглаживания картинки BMP, false - сглаживается/ true - не сглаживается
	*@ param noneResize - флаг ресайза, если true - ресайза нет, если false - есть
	*@ param useBitmap - использовать ли битмапу для хранения изображения
	*@ param effect - строка с типом эффекта
	*/
	public function ImageViewer(target:MovieClip,
								url:String,
								width:Number,
								height:Number,
								align:String, 
								borderEnable:Boolean,
								fadeEnable:Boolean, 
								borderStyle:Object,
								sharpBMP:Boolean, 
								noneResize:Boolean, 
								useBitmap:Boolean,
								effect:String)
	{
		
		this.target = target;
		this.url = url;
		this.width = width;
		this.height = height;
		this.align = align;
		this.borderEnable = borderEnable;
		this.fadeEnable = fadeEnable;
		this.borderStyle = borderStyle;
		this.sharpBMP = Boolean(sharpBMP);
		//trace('!!!noneResize = ' + noneResize)
		this.noneResize = Boolean(noneResize);
		this.useBitmap = useBitmap;
		effectType = effect;
		//trace(effectType)
		//trace('effectType = '+effectType)
		init();
	}	
	
	//// METHODS
	//	private
	private function init():Void
	{
		BORDER_THICKNESS = 1;
		BORDER_ALPHA = 100;
		BORDER_COLOR = 0x00000;
		FADE_IN_TIME = 0.6;
		DEFAULT_BORDER_STYLE = new Object();
		DEFAULT_BORDER_STYLE.thickness = BORDER_THICKNESS;
		DEFAULT_BORDER_STYLE.color = BORDER_COLOR;
		DEFAULT_BORDER_STYLE.alpha = BORDER_ALPHA;
		DEFAULT_BORDER_STYLE.indent = 0;
		loadingCollector = new Object();
		loadingCollector.bytesTotal = 0;
		loadingCollector.bytesLoaded = 0;
		createContainers();
		loader = new MovieClipLoader();	// настройка лоадера
		loader.addListener(this);
		loadImage();
	}
	
	private function createContainers():Void		// создает все контейнеры
	{
		var containerDepth:Number = target.getNextHighestDepth();
		container = target.createEmptyMovieClip('container' + containerDepth, containerDepth);
		if(fadeEnable){container._alpha = 0;}
		//container._alpha = 0;
		
		EFFECT_DEPTH = container.getNextHighestDepth();
		IMAGE_DEPTH = EFFECT_DEPTH + 1;
		MASK_DEPTH = IMAGE_DEPTH + 1;
		BORDER_DEPTH = MASK_DEPTH + 1;
		imageEffect = container.createEmptyMovieClip('imageEffect', EFFECT_DEPTH);
		image = container.createEmptyMovieClip('image', IMAGE_DEPTH);
		mask = container.createEmptyMovieClip('mask', MASK_DEPTH);
		border = container.createEmptyMovieClip('border', BORDER_DEPTH);
		image.cacheAsBitmap = true;
	}
	private function createMask(w:Number, h:Number):Void
	{
		mask.clear();
		mask.beginFill(0x000000, 100);
		mask.moveTo(0, 0);
		mask.lineTo(w, 0);
		mask.lineTo(w, h);
		mask.lineTo(0, h);
		mask.lineTo(0, 0);
		mask.endFill();
		image.setMask(mask);
	}
	private function loadImage():Void
	{
		//trace(loader)
		loader.loadClip(url, image);
	}
	
	private function setSize(_w:Number, _h:Number):Object
	{
		var ret:Object = new Object();
		ret.h = _h;
		ret.w = _w;
		if(_w !=0 && _h != 0)
		{
			var newWH:Object = getNewWH(_w, _h, image);
			trace([newWH.w, newWH.h])
			// проверка на соотв. размеров
			newWH.h = Math.round(newWH.h);
			newWH.w = Math.round(newWH.w);
			//trace(image._height)
			if(newWH.h != Math.round(image._height) || newWH.w != Math.round(image._width))
			{
				image._height = newWH.h;
				image._width = newWH.w;
				
			};
			ret.h = newWH.h;
			ret.w = newWH.w;
		}
		return ret;
	}
	private function setAlign():Void	// выравнивание
	{
		/*
		"T" По верхнему краю По центру
		"B" По нижнему краю По центру
		"L" По центру По левому краю
		"R" По центру По правому краю
		"TL" По верхнему краю По левому краю
		"TR" По верхнему краю По правому краю
		"BL" По нижнему краю По левому краю
		"BR" По нижнему краю По правому краю
		"C" По центру, По центру
		*/
		//if(align == 'T' || )
		var x:Number = container._x;	// новые координаты контейнера
		var y:Number = container._y;
		switch(align)
		{
			case 'T':
				//trace('align = '+align)
				x += (target._width - image._width)/2;
				y = 0;
			break;
			
			case 'B':
				x += (target._width - image._width)/2;
				y += target._height  - image._height;
			break;
			
			case 'L':
				x += 0;
				y += (height  - image._height)/2;
				//trace(y)
			break;
			
			case 'R':
				x += height - image._width;
				y += (height  - image._height)/2;
				//trace('target._width = '+target._width)
			break;
			
			case 'TL':
			//trace('TL')
				x += 0;
				y += 0;
			break;
			
			case 'TR':
				x += target._width - image._width;
				y += 0;
			break;
			
			case 'BL':
				x += 0;
				y += target._height  - image._height;
			break;
			
			case 'BR':
				x += target._width - image._width;
				y += target._height  - image._height;
			break;
			
			case 'C':
				x += (width - image._width)/2;
				y += (height  - image._height)/2;
				//trace([x, y]);
				//trace([target._height, image._height]);
			break;
			
			default :
				
			break;
		}
		//trace([x, y])
		container._x = x;
		container._y = y;
	}
	
	private function createBorder(w:Number, h:Number, style:Object):Void
	{
		
		var thickness:Number = style.thickness;
		var color:Number = style.color;
		var alpha:Number = style.alpha;
		var indent:Number = style.indent;
		if(thickness == undefined || thickness == null || isNaN(thickness))
		{
			thickness = DEFAULT_BORDER_STYLE.thickness;
		};
		if(color == undefined || color == null || isNaN(color))
		{
			color = DEFAULT_BORDER_STYLE.color;
		};
		if(alpha == undefined || alpha == null || isNaN(alpha))
		{
			alpha = DEFAULT_BORDER_STYLE.alpha;
		};
		if(indent == undefined || indent == null || isNaN(indent))
		{
			indent = DEFAULT_BORDER_STYLE.indent;
		};
		if(borderEnable)
		{
			//trace(style.thickness)
			border.clear();
			border.lineStyle(thickness, color, alpha);
			border.moveTo(-indent, -indent);
			border.lineTo(w + indent, -indent);
			border.lineTo(w + indent, h + indent);
			border.lineTo(-indent, h +indent);
			border.lineTo(-indent, -indent);
		}
	}
	
	private function fadeIn(mc:MovieClip):Void
	{
			mc._alpha = 100;
			fadeInManager = new TransitionManager(mc);
			fadeInManager.startTransition({type:mx.transitions.Fade, direction:Transition.IN, duration:FADE_IN_TIME, easing:mx.transitions.easing.None.easeOut});
	}
	// функция подгонки высоты и ширины изображения под размеры контейнера носителя
	private function getNewWH(widthBox:Number, heightBox:Number, clip_mc:MovieClip):Object
	{
		var newWH:Object = {w:0, h:0};
		var koeff:Number;
		var w:Number = clip_mc._width;
		var h:Number = clip_mc._height;
		
			koeff = w/(widthBox);
			newWH.w = widthBox;
			newWH.h = Math.round(h/koeff);
			//trace([widthBox, heightBox]);
			//trace([newWH.w, newWH.h]);
			
			if(newWH.h>heightBox)
			{
				koeff = h/(heightBox);
				newWH.w = Math.round(w/koeff);
				newWH.h = Math.round(heightBox);
			};
			//trace((newWH.w>widthBox));
			if(newWH.w>widthBox)
			{
				newWH.w = widthBox;
				newWH.h = Math.round(h/koeff);
			};
			
		return newWH;
	}
	//// EVENTS HANDLERS
	private function onLoadProgress(__target:MovieClip,bytesLoaded:Number,bytesTotal:Number):Void
	{
		var t:ImageViewer = this;
		var eventObject:Object = new Object();
		eventObject.target = __target;
		eventObject.bytesLoaded = bytesLoaded;
		eventObject.bytesTotal = bytesTotal;
		if(bytesTotal>0)
		{
			t.loadingCollector.bytesTotal = eventObject.bytesTotal;
			t.loadingCollector.bytesLoaded = eventObject.bytesLoaded;
			t.onProgress(eventObject);
		}
	}
	//выполняется при загрузке файла
	private function onLoadInit(__target:MovieClip):Void
	{
		var t:ImageViewer = this;
		loader.removeListener(this);
		if(useBitmap)
		{
			// делаем битпаму
			var w:Number = __target._width;
			var h:Number = __target._height;
			var transparent:Boolean = true;
			var fillColor:Number = 0xFFFFFFFF;
			
			btmImage = new BitmapData(w, h, transparent, fillColor);
			btmImage.draw(image);
			image.removeMovieClip();
			image = container.createEmptyMovieClip('image', IMAGE_DEPTH);
			image.attachBitmap(btmImage, 0, "auto", sharpBMP);
			//image._alpha = 0;
			
			
			if(effectType)
			{
				imageEffect.cacheAsBitmap = true;
				imageEffect.attachBitmap(btmImage, 0, "auto", sharpBMP);
				imageEffect._alpha = 100;
			}
			// применение эффекта
			//trace('onLoadINIT')
			//trace('effectType = '+effectType)
			switch(effectType)
			{
				
				case 'black_white':
				//trace('black_white')
				var colorMatrix_filter = new ColorMatrixFilter([0.100000001490116,0.100000001490116,0.0299999993294477,0,0,0.100000001490116,0.100000001490116,0.0299999993294477,0,0,0.100000001490116,0.100000001490116,0.0299999993294477,0,0,0,0,0,1,0]);
				//0.100000001490116,0.100000001490116,0.0299999993294477,0,0,0.100000001490116,0.100000001490116,0.0299999993294477,0,0,0.100000001490116,0.100000001490116,0.0299999993294477,0,0,0,0,0,1,0
				imageEffect.filters = new Array(colorMatrix_filter);
				break;
			};
		}
		else
		{
			
		};
		//trace('noneResize = ' + noneResize);
		if(!noneResize)		// если ресайз нужен...
		{
			var size:Object = setSize(width, height);	// получаем размеры изображения
		};
		//createMask(size.w, size.h);					// после всех манипуляций вешаем маску
		//trace('image._height = ' + target._height);
		setAlign();									// делаем выравнивание относительно контейнера
		createBorder(image._width, image._height, borderStyle);	// рамка
		if(fadeEnable)
		{
			fadeIn(container);
		}
		t.onLoad(t.container);
		
	}
	
	//функция отображает ошибки возникающие при загрузке
	private function onLoadError(__target:MovieClip,errorCode:String):Void
	{
		var t:ImageViewer = this;
		var eventObject:Object = new Object();
		eventObject.url = t.url;
		eventObject.errorCode = errorCode;
		t.onError(eventObject);
		//trace('error')
	}
	// 	public
	public function get content():MovieClip
	{
		return container;
	}
	
	public function destroy():Void
	{
		loader.removeListener(this);
		delete loader;
		delete btmImage;
		container.removeMovieClip();
	};
	
	public function get loadData():Object
	{
		return loadingCollector;
	};
	
	public function showEffect():Void
	{
		/*trace('effectType = '+effectType)
		trace('image = ' + image)
		trace('imageEffect = ' + imageEffect._width)
		trace('imageEffect.alpha = ' + imageEffect._alpha)
		trace('url = ' + url);
		trace('------------------------------')*/
		image.onEnterFrame = function():Void
		{
			if(this._alpha > 0){this._alpha -= 15;}
			else{this._alpha = 0; delete this.onEnterFrame};
		};
		//trace('imageEffect = '+imageEffect)
	};
	
	public function hideEffect():Void
	{
		
		image.onEnterFrame = function():Void
		{
			if(this._alpha < 100){this._alpha += 15;}
			else{this._alpha = 100; delete this.onEnterFrame};
			//trace(this._alpha)
		};
		
	};
}